<%--
  - Copyright 2011 Angel Sanadinov
  -
  - This file is part of VBox WMI.
  -
  - VBox WMI is free software: you can redistribute it and/or modify
  - it under the terms of the GNU General Public License as published by
  - the Free Software Foundation, either version 3 of the License, or
  - (at your option) any later version.
  -
  - VBox WMI is distributed in the hope that it will be useful,
  - but WITHOUT ANY WARRANTY; without even the implied warranty of
  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  - GNU General Public License for more details.
  -
  - You should have received a copy of the GNU General Public License
  - along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
  --%>

<%@page import="Utilities.ApplicationException"%>
<%@page import="Managers.Utilities.RequestResponseWrapper"%>
<%@page import="Utilities.ExceptionMessages"%>
<%@page import="Managers.Utilities.ResponseMessagesContainer"%>
<%@page import="Utilities.Functions"%>
<%@page import="Utilities.Constants.SendingRequestResult" %>
<%@page import="java.util.ArrayList"%>
<%@page import="Beans.Requests.MachineManagement.CreateMachineRequest"%>
<%@page import="Beans.Requests.MachineManagement.Components.ControllerSettings"%>
<%@page import="org.virtualbox_3_2.StorageControllerType"%>
<%@page import="org.virtualbox_3_2.StorageBus"%>
<%@page import="Beans.Requests.MediumManagement.MediumManagementRequest"%>
<%@page import="Beans.Requests.MachineManagement.Components.DeviceSettings"%>
<%@page import="org.virtualbox_3_2.MediumVariant"%>
<%@page import="Beans.Requests.MediumManagement.CreateHardDiskRequest"%>
<%@page import="Beans.Requests.MachineManagement.Components.NetworkAdapterLiveSettings"%>
<%@page import="Beans.Requests.MachineManagement.Components.SharedFolderSettings"%>
<%@page import="org.virtualbox_3_2.NATProtocol"%>
<%@page import="Beans.Requests.MachineManagement.Components.NATEngineForwardingRule"%>
<%@page import="Utilities.Constants"%>
<%@page import="Beans.Requests.MachineManagement.Components.NATEngineSettings"%>
<%@page import="org.virtualbox_3_2.NetworkAttachmentType"%>
<%@page import="org.virtualbox_3_2.NetworkAdapterType"%>
<%@page import="Beans.Requests.MachineManagement.Components.NetworkAdapterSettings"%>
<%@page import="Beans.Requests.MachineManagement.Components.VideoSettings"%>
<%@page import="org.virtualbox_3_2.VRDPAuthType"%>
<%@page import="Beans.Requests.MachineManagement.Components.VRDPSettings"%>
<%@page import="Beans.Requests.MachineManagement.Components.CPUSettings"%>
<%@page import="Beans.Requests.MachineManagement.Components.IOSettings"%>
<%@page import="Beans.Requests.MachineManagement.Components.MemorySettings"%>
<%@page import="Beans.Requests.MachineManagement.Components.BootSettings"%>
<%@page import="org.virtualbox_3_2.DeviceType"%>
<%@page import="org.virtualbox_3_2.AudioDriverType"%>
<%@page import="org.virtualbox_3_2.AudioControllerType"%>
<%@page import="org.virtualbox_3_2.BIOSBootMenuMode"%>
<%@page import="org.virtualbox_3_2.FirmwareType"%>
<%@page import="Beans.Requests.MachineManagement.Components.BIOSSettings"%>
<%@page import="Beans.Requests.MachineManagement.Components.AudioSettings"%>
<%@page import="Utilities.Constants.MachineSnapshotManagementAction"%>
<%@page import="Beans.Requests.MachineManagement.RemoveMachineRequest"%>
<%@page import="Beans.Requests.MachineManagement.Components.MediumMountSettings"%>
<%@page import="Beans.Requests.MachineManagement.MountMediumRequest"%>
<%@page import="Beans.Requests.MachineManagement.Components.StorageSettings"%>
<%@page import="Beans.Requests.MachineManagement.ModifyMachineStorageRequest"%>
<%@page import="Beans.Requests.MachineManagement.ModifyMachineLiveSettingsRequest"%>
<%@page import="Beans.Requests.MachineManagement.ModifyMachineAttributesRequest"%>
<%@page import="Beans.Requests.MachineManagement.ManageMachineSnapshotsRequest"%>
<%@page import="Utilities.Constants.MachineStateChangeAction"%>
<%@page import="Beans.Requests.MachineManagement.ChangeMachineExecutionStateRequest"%>
<%@page import="Beans.Responses.MachineManagementResponse"%>
<%@page import="Managers.Utilities.User"%>
<%@page import="Utilities.ParameterNames"%>
<%@page import="Utilities.ParameterNames.Service"%>
<%@page import="Beans.Requests.MachineManagement.MachineManagementRequest"%>
<%@page import="Utilities.UIFunctions"%>
<%
    //retrieves user data from the session
    User userSessionData = (User)session.getAttribute(ParameterNames.SESSION_USER_OBJECT);

    //attempts to retrieve the requested action
    int action = 0;
    try
    {
        action = Integer.parseInt(request.getParameter("action"));
    }
    catch(NumberFormatException e){}

    //builds the requested action, based on the action id
    MachineManagementRequest machineRequest = null;
    switch(action)
    {
        //create new machine request
        case 1:
        {
            //retrieves the supplied parameters and builds the request object
            machineRequest = new CreateMachineRequest(userSessionData.getUserData().getUserId(),
                                                      userSessionData.getCurrentServerId(),
                                                      request.getParameter("create.machine.permissions"));

            CreateMachineRequest creationRequest = (CreateMachineRequest)machineRequest;

            creationRequest.setMachineName(request.getParameter("create.machine.name"));
            creationRequest.setOsTypeId(request.getParameter("create.machine.osType"));
            creationRequest.setMachineDescription(request.getParameter("create.machine.description"));

            if(request.getParameter("create.machine.audio.configure") != null)
            {
                AudioSettings audioSettings = new AudioSettings(request.getParameter("create.machine.audio.enable") != null,
                                                                AudioControllerType.valueOf(request.getParameter("create.machine.audio.controllerType")),
                                                                AudioDriverType.valueOf(request.getParameter("create.machine.audio.driverType")));
                creationRequest.setAudioSettings(audioSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.bios.configure") != null)
            {
                long timeOffset = 0;
                try
                {
                    timeOffset = Long.parseLong(request.getParameter("create.machine.bios.timeOffset"));
                }
                catch(NumberFormatException e){}

                BIOSSettings biosSettings = new BIOSSettings(FirmwareType.valueOf(request.getParameter("create.machine.bios.firmware")),
                                                             request.getParameter("create.machine.bios.hpetEnabled") != null,
                                                             request.getParameter("create.machine.bios.RTCinUTC") != null,
                                                             BIOSBootMenuMode.valueOf(request.getParameter("create.machine.bios.bootMenuMode")),
                                                             request.getParameter("create.machine.bios.acpiEnabled") != null,
                                                             request.getParameter("create.machine.bios.ioapicEnabled") != null,
                                                             timeOffset);

                creationRequest.setBiosSettings(biosSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.boot.configure") != null)
            {
                int numberOfBootDevices = 4;
                DeviceType[] devices = new DeviceType[numberOfBootDevices];

                for(int i = 0; i < numberOfBootDevices; i++)
                    devices[i] = DeviceType.valueOf(request.getParameter("create.machine.boot.slot" + i));

                BootSettings bootSettings = new BootSettings(devices);
                creationRequest.setBootSettings(bootSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.cpu.configure") != null)
            {
                int cpuCount = 0;
                try
                {
                    cpuCount = Integer.parseInt(request.getParameter("create.machine.cpu.count"));
                }
                catch(NumberFormatException e){}

                CPUSettings cpuSettings = new CPUSettings(request.getParameter("create.machine.cpu.hotPluggingEnabled") != null, cpuCount);
                creationRequest.setCpuSettings(cpuSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.io.configure") != null)
            {
                int cacheSize = 0;
                int cacheMaxBandwidth = 0;

                try
                {
                    cacheSize = Integer.parseInt(request.getParameter("create.machine.io.cacheSize"));
                    cacheMaxBandwidth = Integer.parseInt(request.getParameter("create.machine.io.cacheMaxBandwidth"));
                }
                catch(NumberFormatException e){}

                IOSettings ioSettings = new IOSettings(request.getParameter("create.machine.io.cacheEnabled") != null,
                                                       cacheSize,
                                                       cacheMaxBandwidth);
                creationRequest.setIoSettings(ioSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.memory.configure") != null)
            {
                int ramSize = 0;
                int ramBalloonSize = 0;

                try
                {
                    ramSize = Integer.parseInt(request.getParameter("create.machine.memory.ramSize"));
                    ramBalloonSize = Integer.parseInt(request.getParameter("create.machine.memory.ramBalloonSize"));
                }
                catch(NumberFormatException e){}

                MemorySettings memorySettings = new MemorySettings(ramSize,
                                                                   ramBalloonSize,
                                                                   request.getParameter("create.machine.memory.pageFusionEnabled") != null);
                creationRequest.setMemorySettings(memorySettings);
            }
            else
                ;

            if(request.getParameter("create.machine.networks.configure") != null)
            {
                int numberOfAdapters = 8;
                NetworkAdapterSettings[] networksSettings = new NetworkAdapterSettings[numberOfAdapters];

                for(int i = 0; i < numberOfAdapters; i++)
                {
                    if(request.getParameter("create.machine.adapter" + i+ ".enabled") != null)
                    {
                        String parameterPrefix = "create.machine.adapter" + i + ".";

                        int adapterLineSpeed = 0;
                        try
                        {
                            adapterLineSpeed = Integer.parseInt(request.getParameter(parameterPrefix + "lineSpeed"));
                        }
                        catch(NumberFormatException e){}

                        networksSettings[i] = new NetworkAdapterSettings(NetworkAdapterType.valueOf(request.getParameter(parameterPrefix + "adapterType")),
                                                                         NetworkAttachmentType.valueOf(request.getParameter(parameterPrefix + "attachmentType")),
                                                                         request.getParameter(parameterPrefix + "adapterState") != null,
                                                                         request.getParameter(parameterPrefix + "MAC"),
                                                                         request.getParameter(parameterPrefix + "networkName"),
                                                                         null,
                                                                         request.getParameter(parameterPrefix + "cable") != null,
                                                                         adapterLineSpeed);
                    }
                    else
                        networksSettings[i] = null;
                }

                creationRequest.setNetworksSettings(networksSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.folders.configure") != null)
            {
                //hidden field to carry the number of folders
                int numberOfFolders = 0;
                try
                {
                    numberOfFolders = Integer.parseInt(request.getParameter("create.machine.folders.newNumber"));
                }
                catch(NumberFormatException e){}

                ArrayList<SharedFolderSettings> sharedFoldersSettings = new ArrayList<SharedFolderSettings>(numberOfFolders);

                for(int i = 0; i < numberOfFolders; i++)
                {
                    String parameterPrefix = "create.machine.folders.newFolder" + i + ".";
                    sharedFoldersSettings.add(new SharedFolderSettings(request.getParameter(parameterPrefix + "name"),
                                                                       request.getParameter(parameterPrefix + "hostPath"),
                                                                       request.getParameter(parameterPrefix + "writable") != null));
                }

                creationRequest.setSharedFoldersSettings(sharedFoldersSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.storage.configure") != null)
            {
                StorageSettings storageSettings = new StorageSettings();

                int numberOfControllers = 0;
                int numberOfAttachments = 0;

                try
                {
                    numberOfControllers = Integer.parseInt(request.getParameter("create.machine.controllers.newNumber"));
                }
                catch(NumberFormatException e){}

                try
                {
                    numberOfAttachments = Integer.parseInt(request.getParameter("create.machine.attachments.newNumber"));
                }
                catch(NumberFormatException e){}

                for(int i = 0; i < numberOfControllers; i++)
                {
                    String parameterPrefix = "create.machine.controllers.newController" + i + ".";
                    storageSettings.addStorageController(new ControllerSettings(request.getParameter(parameterPrefix + "name"),
                                                                                StorageBus.valueOf(request.getParameter(parameterPrefix + "connectionType")),
                                                                                StorageControllerType.valueOf(request.getParameter(parameterPrefix + "controllerType")),
                                                                                request.getParameter(parameterPrefix + "hostIOCache") != null));
                }

                for(int i = 0; i < numberOfAttachments; i++)
                {
                    String parameterPrefix = "create.machine.attachments.newAttachment" + i + ".";

                    int controllerPort = -1;
                    int controllerSlot = -1;
                    try
                    {
                        controllerPort = Integer.parseInt(request.getParameter(parameterPrefix + "controllerPort"));
                        controllerSlot = Integer.parseInt(request.getParameter(parameterPrefix + "controllerSlot"));
                    }
                    catch(NumberFormatException e){}

                    DeviceSettings deviceSettings = new DeviceSettings(request.getParameter(parameterPrefix + "controllerName"),
                                                                       controllerPort,
                                                                       controllerSlot,
                                                                       DeviceType.valueOf(request.getParameter(parameterPrefix + "deviceType")),
                                                                       request.getParameter(parameterPrefix + "mediumId"));

                    if(request.getParameter(parameterPrefix + "newMedium") != null)
                    {
                        MediumManagementRequest mediumRequestData = null;

                        String format = request.getParameter(parameterPrefix + "newMedium.format");
                        String location = request.getParameter(parameterPrefix + "newMedium.location");
                        MediumVariant variant = MediumVariant.valueOf(request.getParameter(parameterPrefix + "newMedium.variant"));
                        String permissions = request.getParameter(parameterPrefix + "newMedium.permissions");

                        if(request.getParameter(parameterPrefix + "newMedium").equals("1"))
                        {
                            long logicalSize = 0;
                            try
                            {
                                logicalSize = Long.parseLong(request.getParameter(parameterPrefix + "newMedium.size"));
                            }
                            catch(NumberFormatException e){}

                            mediumRequestData = new CreateHardDiskRequest(userSessionData.getUserData().getUserId(),
                                                                          userSessionData.getCurrentServerId(),
                                                                          format,
                                                                          location,
                                                                          variant,
                                                                          logicalSize,
                                                                          permissions);
                        }
                        else if(request.getParameter(parameterPrefix + "newMedium").equals("2"))
                        {
                            mediumRequestData = new CreateHardDiskRequest(userSessionData.getUserData().getUserId(),
                                                                          userSessionData.getCurrentServerId(),
                                                                          format,
                                                                          location,
                                                                          variant,
                                                                          permissions,
                                                                          request.getParameter(parameterPrefix + "newMedium.parentId"));
                        }
                        else
                            ;

                        storageSettings.attachNewMedium(deviceSettings, mediumRequestData);
                    }
                    else
                        storageSettings.attachExistingMedium(deviceSettings);
                }

                creationRequest.setStorageSettings(storageSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.vrdp.configure") != null)
            {
                int timeout = 0;
                int videoChannelQuality = 0;

                try
                {
                    timeout = Integer.parseInt(request.getParameter("create.machine.vrdp.timeout"));
                    videoChannelQuality = Integer.parseInt(request.getParameter("create.machine.vrdp.videoChannelQuality"));
                }
                catch(NumberFormatException e){}

                VRDPSettings vrdpSettings = new VRDPSettings(request.getParameter("create.machine.vrdp.serverEnabled") != null,
                                                             null,
                                                             request.getParameter("create.machine.vrdp.serverAddress"),
                                                             VRDPAuthType.valueOf(request.getParameter("create.machine.vrdp.authType")),
                                                             timeout,
                                                             request.getParameter("create.machine.vrdp.allowMultipleConnections") != null,
                                                             request.getParameter("create.machine.vrdp.reuseSingleConnection") != null,
                                                             request.getParameter("create.machine.vrdp.videoChannelEnabled") != null,
                                                             videoChannelQuality);
                creationRequest.setVrdpSettings(vrdpSettings);
            }
            else
                ;

            if(request.getParameter("create.machine.video.configure") != null)
            {
                int vramSize = 0;
                try
                {
                    vramSize = Integer.parseInt(request.getParameter("create.machine.video.vramSize"));
                }
                catch(NumberFormatException e){}

                VideoSettings videoSettings = new VideoSettings(vramSize,
                                                                request.getParameter("create.machine.video.3DEnabled") != null,
                                                                request.getParameter("create.machine.video.2DEnabled") != null);
                creationRequest.setVideoSettings(videoSettings);
            }
            else
                ;
        } break;

        //change machine state request
        case 2:
        {
            //attempts to retrieve and parse the requested machine state
            MachineStateChangeAction state = null;
            try
            {
                int parameterState = Integer.parseInt(request.getParameter("state"));
                switch(parameterState)
                {
                    case 1: state = MachineStateChangeAction.POWER_UP; break;
                    case 2: state = MachineStateChangeAction.POWER_DOWN; break;
                    case 3: state = MachineStateChangeAction.RESET; break;
                    case 4: state = MachineStateChangeAction.PAUSE; break;
                    case 5: state = MachineStateChangeAction.SAVE; break;
                    case 6: state = MachineStateChangeAction.RESUME; break;
                    case 7: state = MachineStateChangeAction.ACPI_POWER; break;
                    case 8: state = MachineStateChangeAction.ACPI_SLEEP; break;
                    default: state = MachineStateChangeAction.INVALID_ACTION;
                }
            }
            catch(NumberFormatException e)
            {}

            //builds the request object
            machineRequest = new ChangeMachineExecutionStateRequest(userSessionData.getUserData().getUserId(),
                                                                    userSessionData.getCurrentServerId(),
                                                                    request.getParameter("id"),
                                                                    state);
        } break;

        //manage machine snapshots request
        case 3:
        {
            //retrieves the requested snapshot operation
            int snapshotOperation = 0;
            try
            {
                snapshotOperation = Integer.parseInt(request.getParameter("operation"));
            }
            catch(NumberFormatException e){}

            switch(snapshotOperation)
            {
                //create snapshot request
                case 1:
                {
                    machineRequest = new ManageMachineSnapshotsRequest(userSessionData.getUserData().getUserId(),
                                                                       userSessionData.getCurrentServerId(),
                                                                       request.getParameter("id"),
                                                                       request.getParameter("create.snapshot.name"),
                                                                       request.getParameter("create.snapshot.description"));
                } break;

                //modify snapshot request
                case 2:
                {
                    machineRequest = new ManageMachineSnapshotsRequest(userSessionData.getUserData().getUserId(),
                                                                       userSessionData.getCurrentServerId(),
                                                                       request.getParameter("id"),
                                                                       request.getParameter("modify.snapshot.name"),
                                                                       request.getParameter("modify.snapshot.description"),
                                                                       request.getParameter("modif.snapshot.snapshotId"));
                } break;

                //restore snapshot request
                case 3:
                {
                    machineRequest = new ManageMachineSnapshotsRequest(userSessionData.getUserData().getUserId(),
                                                                       userSessionData.getCurrentServerId(),
                                                                       request.getParameter("id"),
                                                                       request.getParameter("snapshotId"),
                                                                       MachineSnapshotManagementAction.RESTORE);
                } break;

                //remove snapshot request
                case 4:
                {
                    machineRequest = new ManageMachineSnapshotsRequest(userSessionData.getUserData().getUserId(),
                                                                       userSessionData.getCurrentServerId(),
                                                                       request.getParameter("id"),
                                                                       request.getParameter("snapshotId"),
                                                                       MachineSnapshotManagementAction.REMOVE);
                } break;

                default: ;
            }
        } break;

        //modify machine offline attributes request
        case 4:
        {
            //retrieves the supplied parameters and builds the request object
            machineRequest = new ModifyMachineAttributesRequest(userSessionData.getUserData().getUserId(),
                                                                userSessionData.getCurrentServerId(),
                                                                request.getParameter("id"));

            if(request.getParameter("modify.machine.name.configure") != null)
                ((ModifyMachineAttributesRequest)machineRequest).setMachineName(request.getParameter("modify.machine.name"));
            else
                ;

            if(request.getParameter("modify.machine.description.configure") != null)
                ((ModifyMachineAttributesRequest)machineRequest).setMachineDescription(request.getParameter("modify.machine.description"));
            else
                ;

            if(request.getParameter("modify.machine.permissions.configure") != null)
                ((ModifyMachineAttributesRequest)machineRequest).setPermissions(request.getParameter("modify.machine.permissions"));
            else
                ;

            if(request.getParameter("modify.machine.newOwner.configure") != null)
            {
                int newOwnerId = Constants.INVALID_USER_ID;
                try
                {
                    newOwnerId = Integer.parseInt(request.getParameter("modify.machine.newOwner"));
                }
                catch(NumberFormatException e){}

                ((ModifyMachineAttributesRequest)machineRequest).setNewOwnerId(newOwnerId);
            }
            else
                ;

            if(request.getParameter("modify.machine.audio.configure") != null)
            {
                AudioSettings audioSettings = new AudioSettings(request.getParameter("modify.machine.audio.enable") != null,
                                                                AudioControllerType.valueOf(request.getParameter("modify.machine.audio.controllerType")),
                                                                AudioDriverType.valueOf(request.getParameter("modify.machine.audio.driverType")));
                ((ModifyMachineAttributesRequest)machineRequest).setAudioSettings(audioSettings);
            }
            else
                ;

            if(request.getParameter("modify.machine.bios.configure") != null)
            {
                long timeOffset = 0;
                try
                {
                    timeOffset = Long.parseLong(request.getParameter("modify.machine.bios.timeOffset"));
                }
                catch(NumberFormatException e){}

                BIOSSettings biosSettings = new BIOSSettings(FirmwareType.valueOf(request.getParameter("modify.machine.bios.firmware")),
                                                             request.getParameter("modify.machine.bios.hpetEnabled") != null,
                                                             request.getParameter("modify.machine.bios.RTCinUTC") != null,
                                                             BIOSBootMenuMode.valueOf(request.getParameter("modify.machine.bios.bootMenuMode")),
                                                             request.getParameter("modify.machine.bios.acpiEnabled") != null,
                                                             request.getParameter("modify.machine.bios.ioapicEnabled") != null,
                                                             timeOffset);

                ((ModifyMachineAttributesRequest)machineRequest).setBiosSettings(biosSettings);
            }
            else
                ;

            if(request.getParameter("modify.machine.boot.configure") != null)
            {
                int numberOfBootDevices = 4;
                DeviceType[] devices = new DeviceType[numberOfBootDevices];

                for(int i = 0; i < numberOfBootDevices; i++)
                    devices[i] = DeviceType.valueOf(request.getParameter("modify.machine.boot.slot" + i));

                BootSettings bootSettings = new BootSettings(devices);
                ((ModifyMachineAttributesRequest)machineRequest).setBootSettings(bootSettings);
            }
            else
                ;

            if(request.getParameter("modify.machine.cpu.configure") != null)
            {
                int cpuCount = 0;
                try
                {
                    cpuCount = Integer.parseInt(request.getParameter("modify.machine.cpu.count"));
                }
                catch(NumberFormatException e){}

                CPUSettings cpuSettings = new CPUSettings(request.getParameter("modify.machine.cpu.hotPluggingEnabled") != null, cpuCount);
                ((ModifyMachineAttributesRequest)machineRequest).setCpuSettings(cpuSettings);
            }
            else
                ;

            if(request.getParameter("modify.machine.io.configure") != null)
            {
                int cacheSize = 0;
                int cacheMaxBandwidth = 0;

                try
                {
                    cacheSize = Integer.parseInt(request.getParameter("modify.machine.io.cacheSize"));
                    cacheMaxBandwidth = Integer.parseInt(request.getParameter("modify.machine.io.cacheMaxBandwidth"));
                }
                catch(NumberFormatException e){}

                IOSettings ioSettings = new IOSettings(request.getParameter("modify.machine.io.cacheEnabled") != null,
                                                       cacheSize,
                                                       cacheMaxBandwidth);
                ((ModifyMachineAttributesRequest)machineRequest).setIoSettings(ioSettings);
            }
            else
                ;

            if(request.getParameter("modify.machine.memory.configure") != null)
            {
                int ramSize = 0;
                int ramBalloonSize = 0;

                try
                {
                    ramSize = Integer.parseInt(request.getParameter("modify.machine.memory.ramSize"));
                    ramBalloonSize = Integer.parseInt(request.getParameter("modify.machine.memory.ramBalloonSize"));
                }
                catch(NumberFormatException e){}

                MemorySettings memorySettings = new MemorySettings(ramSize,
                                                                   ramBalloonSize,
                                                                   request.getParameter("modify.machine.memory.pageFusionEnabled") != null);
                ((ModifyMachineAttributesRequest)machineRequest).setMemorySettings(memorySettings);
            }
            else
                ;
            
            if(request.getParameter("modify.machine.networks.configure") != null)
            {
                int numberOfAdapters = 8;
                NetworkAdapterSettings[] networksSettings = new NetworkAdapterSettings[numberOfAdapters];

                for(int i = 0; i < numberOfAdapters; i++)
                {
                    if(request.getParameter("modify.machine.adapter" + i+ ".configure") != null)
                    {
                        String parameterPrefix = "modify.machine.adapter" + i + ".";

                        int adapterLineSpeed = 0;
                        try
                        {
                            adapterLineSpeed = Integer.parseInt(request.getParameter(parameterPrefix + "lineSpeed"));
                        }
                        catch(NumberFormatException e){}

                        networksSettings[i] = new NetworkAdapterSettings(NetworkAdapterType.valueOf(request.getParameter(parameterPrefix + "adapterType")),
                                                                         NetworkAttachmentType.valueOf(request.getParameter(parameterPrefix + "attachmentType")),
                                                                         true,
                                                                         request.getParameter(parameterPrefix + "MAC"),
                                                                         request.getParameter(parameterPrefix + "networkName"),
                                                                         null,
                                                                         request.getParameter(parameterPrefix + "cable") != null,
                                                                         adapterLineSpeed);

                        try
                        {
                            int bootPriority = Integer.parseInt(request.getParameter(parameterPrefix + "bootPriority"));
                            networksSettings[i].setBootPriority(bootPriority);
                        }
                        catch(NumberFormatException e){}

                        if(networksSettings[i].getAttachmentType() == NetworkAttachmentType.NAT)
                        {
                            NATEngineSettings natEngine = new NATEngineSettings();

                            if(request.getParameter(parameterPrefix + "natEngine.mainConfig.configure") != null)
                            {
                                long MTU = 0, socketSendBufferCapacity = 0, socketReceiveBufferCapacity = 0, initialTCPWindowSendingSize = 0,
                                     initialTCPWindowReceivingSize = 0;

                                try
                                {
                                    MTU = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.mtu"));
                                    socketSendBufferCapacity = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.socketSend"));
                                    socketReceiveBufferCapacity = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.socketReceive"));
                                    initialTCPWindowSendingSize = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.initialSend"));
                                    initialTCPWindowReceivingSize = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.initialReceive"));
                                }
                                catch(NumberFormatException e){}

                                natEngine.setEngineConfiguration(MTU,
                                                                 socketSendBufferCapacity,
                                                                 socketReceiveBufferCapacity,
                                                                 initialTCPWindowSendingSize,
                                                                 initialTCPWindowReceivingSize,
                                                                 request.getParameter(parameterPrefix + "natEngine.mainConfig.networkName"),
                                                                 request.getParameter(parameterPrefix + "natEngine.mainConfig.hostIp"));
                            }
                            else
                                ;

                            if(request.getParameter(parameterPrefix + "natEngine.tftpConfig.configure") != null)
                            {
                                natEngine.setTFTPConfiguration(request.getParameter(parameterPrefix + "natEngine.tftpConfig.prefix"),
                                                               request.getParameter(parameterPrefix + "natEngine.tftpConfig.bootFile"),
                                                               request.getParameter(parameterPrefix + "natEngine.tftpConfig.nextServer"));
                            }
                            else
                                ;

                            if(request.getParameter(parameterPrefix + "natEngine.dnsConfig.configure") != null)
                            {
                                natEngine.setDNSConfiguration(request.getParameter(parameterPrefix + "natEngine.dnsConfig.passHostDomain") != null,
                                                              request.getParameter(parameterPrefix + "natEngine.dnsConfig.dnsProxy") != null,
                                                              request.getParameter(parameterPrefix + "natEngine.dnsConfig.useHostResolver") != null);
                            }
                            else
                                ;

                            if(request.getParameter(parameterPrefix + "natEngine.aliasMode.configure") != null)
                            {
                                try
                                {
                                    long aliasMode = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.aliasMode"));
                                    natEngine.setAliasMode(aliasMode);
                                }
                                catch(NumberFormatException e){}
                            }
                            else
                                ;

                            int numberOfCurrentRules = 0;
                            try
                            {
                                numberOfCurrentRules = Integer.parseInt(request.getParameter(parameterPrefix + "natEngine.numberOfRules"));
                            }
                            catch(NumberFormatException e){}

                            for(int ii = 0; ii < numberOfCurrentRules; ii++)
                            {
                                String rulePrefix = parameterPrefix + "natEngine.rule" + ii + ".";
                                if(request.getParameter(rulePrefix + "remove") != null)
                                    natEngine.removeExistingForwardingRule(request.getParameter(rulePrefix + "name"));
                                else
                                    ;
                            }

                            int numberOfRules = 0;
                            try
                            {
                                numberOfRules = Integer.parseInt(request.getParameter(parameterPrefix + "natEngine.numberOfNewRules"));
                            }
                            catch(NumberFormatException e){}
                            
                            for(int ii = 0; ii < numberOfRules; ii++)
                            {
                                String rulePrefix = parameterPrefix + "natEngine.newRule" + ii + ".";

                                int hostPort = 0, guestPort = 0;
                                try
                                {
                                    hostPort = Integer.parseInt(request.getParameter(rulePrefix + "hostPort"));
                                    guestPort = Integer.parseInt(request.getParameter(rulePrefix + "guestPort"));
                                }
                                catch(NumberFormatException e){}

                                natEngine.addNewForwardingRule(new NATEngineForwardingRule(request.getParameter(rulePrefix + "name"),
                                                                                           NATProtocol.valueOf(request.getParameter(rulePrefix + "protocol")),
                                                                                           request.getParameter(rulePrefix + "hostIP"),
                                                                                           hostPort,
                                                                                           request.getParameter(rulePrefix + "guestIP"),
                                                                                           guestPort));
                            }

                            networksSettings[i].setNatEngineSetup(natEngine);
                        }
                        else
                            ;
                    }
                    else
                        networksSettings[i] = null;
                }

                ((ModifyMachineAttributesRequest)machineRequest).setNetworksSettings(networksSettings);
            }
            else
                ;

            if(request.getParameter("modify.machine.vrdp.configure") != null)
            {
                int timeout = 0;
                int videoChannelQuality = 0;

                try
                {
                    timeout = Integer.parseInt(request.getParameter("modify.machine.vrdp.timeout"));
                    videoChannelQuality = Integer.parseInt(request.getParameter("modify.machine.vrdp.videoChannelQuality"));
                }
                catch(NumberFormatException e){}

                VRDPSettings vrdpSettings = new VRDPSettings(request.getParameter("modify.machine.vrdp.serverEnabled") != null,
                                                             null,
                                                             request.getParameter("modify.machine.vrdp.serverAddress"),
                                                             VRDPAuthType.valueOf(request.getParameter("modify.machine.vrdp.authType")),
                                                             timeout,
                                                             request.getParameter("modify.machine.vrdp.allowMultipleConnections") != null,
                                                             request.getParameter("modify.machine.vrdp.reuseSingleConnection") != null,
                                                             request.getParameter("modify.machine.vrdp.videoChannelEnabled") != null,
                                                             videoChannelQuality);
                ((ModifyMachineAttributesRequest)machineRequest).setVrdpSettings(vrdpSettings);
            }
            else
                ;

            if(request.getParameter("modify.machine.video.configure") != null)
            {
                int vramSize = 0;
                try
                {
                    vramSize = Integer.parseInt(request.getParameter("modify.machine.video.vramSize"));
                }
                catch(NumberFormatException e){}

                VideoSettings videoSettings = new VideoSettings(vramSize,
                                                                request.getParameter("modify.machine.video.3DEnabled") != null,
                                                                request.getParameter("modify.machine.video.2DEnabled") != null);
                ((ModifyMachineAttributesRequest)machineRequest).setVideoSettings(videoSettings);
            }
            else
                ;
        } break;

        //modify machine live attributes request
        case 5:
        {
            //retrieves the supplied parameters and builds the request object
            machineRequest = new ModifyMachineLiveSettingsRequest(userSessionData.getUserData().getUserId(),
                                                                  userSessionData.getCurrentServerId(),
                                                                  request.getParameter("id"));

            if(request.getParameter("modify.machine.folders.configure") != null)
            {
                int numberOfCurrentFolders = 0;
                try
                {
                    numberOfCurrentFolders = Integer.parseInt(request.getParameter("modify.machine.folders.number"));
                }
                catch(NumberFormatException e){}
                
                for(int i = 0; i < numberOfCurrentFolders; i++)
                {
                    String parameterPrefix = "modify.machine.folders.folder" + i + ".";
                    if(request.getParameter(parameterPrefix + "remove") != null)
                        ((ModifyMachineLiveSettingsRequest)machineRequest).addSharedFolderForRemoval(request.getParameter(parameterPrefix + "name"));
                    else
                        ;
                }

                int numberOfNewFolders = 0;
                try
                {
                    numberOfNewFolders = Integer.parseInt(request.getParameter("modify.machine.folders.newNumber"));
                }
                catch(NumberFormatException e){}

                for(int i = 0; i < numberOfNewFolders; i++)
                {
                    String parameterPrefix = "modify.machine.folders.newFolder" + i + ".";
                    ((ModifyMachineLiveSettingsRequest)machineRequest).
                            addNewSharedFolder(new SharedFolderSettings(request.getParameter(parameterPrefix + "name"),
                                                                        request.getParameter(parameterPrefix + "hostPath"),
                                                                        request.getParameter(parameterPrefix + "writable") != null));
                }

                out.println(numberOfCurrentFolders + "/" + numberOfNewFolders);
            }
            else
                ;

            if(request.getParameter("modify.machine.networks.configure") != null)
            {
                int numberOfAdapters = 8;
                NetworkAdapterLiveSettings[] networksSettings = new NetworkAdapterLiveSettings[numberOfAdapters];
                for(int i = 0; i < numberOfAdapters; i++)
                {
                    if(request.getParameter("modify.machine.adapter" + i + ".configure") != null)
                    {
                        String parameterPrefix = "modify.machine.adapter" + i + ".";

                        int adapterLineSpeed = 0;
                        try
                        {
                            adapterLineSpeed = Integer.parseInt(request.getParameter(parameterPrefix + "lineSpeed"));
                        }
                        catch(NumberFormatException e){}

                        networksSettings[i] = new NetworkAdapterLiveSettings(NetworkAttachmentType.valueOf(request.getParameter(parameterPrefix + "attachmentType")),
                                                                             request.getParameter(parameterPrefix + "networkName"),
                                                                             request.getParameter(parameterPrefix + "cable") != null,
                                                                             adapterLineSpeed);

                        if(networksSettings[i].getAttachmentType() == NetworkAttachmentType.NAT)
                        {
                            NATEngineSettings natEngine = new NATEngineSettings();

                            if(request.getParameter(parameterPrefix + "natEngine.mainConfig.configure") != null)
                            {
                                long MTU = 0, socketSendBufferCapacity = 0, socketReceiveBufferCapacity = 0, initialTCPWindowSendingSize = 0,
                                     initialTCPWindowReceivingSize = 0;

                                try
                                {
                                    MTU = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.mtu"));
                                    socketSendBufferCapacity = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.socketSend"));
                                    socketReceiveBufferCapacity = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.socketReceive"));
                                    initialTCPWindowSendingSize = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.initialSend"));
                                    initialTCPWindowReceivingSize = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.mainConfig.initialReceive"));
                                }
                                catch(NumberFormatException e){}

                                natEngine.setEngineConfiguration(MTU,
                                                                 socketSendBufferCapacity,
                                                                 socketReceiveBufferCapacity,
                                                                 initialTCPWindowSendingSize,
                                                                 initialTCPWindowReceivingSize,
                                                                 request.getParameter(parameterPrefix + "natEngine.mainConfig.networkName"),
                                                                 request.getParameter(parameterPrefix + "natEngine.mainConfig.hostIp"));
                            }
                            else
                                ;

                            if(request.getParameter(parameterPrefix + "natEngine.tftpConfig.configure") != null)
                            {
                                natEngine.setTFTPConfiguration(request.getParameter(parameterPrefix + "natEngine.tftpConfig.prefix"),
                                                               request.getParameter(parameterPrefix + "natEngine.tftpConfig.bootFile"),
                                                               request.getParameter(parameterPrefix + "natEngine.tftpConfig.nextServer"));
                            }
                            else
                                ;

                            if(request.getParameter(parameterPrefix + "natEngine.dnsConfig.configure") != null)
                            {
                                natEngine.setDNSConfiguration(request.getParameter(parameterPrefix + "natEngine.dnsConfig.passHostDomain") != null,
                                                              request.getParameter(parameterPrefix + "natEngine.dnsConfig.dnsProxy") != null,
                                                              request.getParameter(parameterPrefix + "natEngine.dnsConfig.useHostResolver") != null);
                            }
                            else
                                ;

                            if(request.getParameter(parameterPrefix + "natEngine.aliasMode.configure") != null)
                            {
                                long aliasMode = 0;
                                try
                                {
                                    aliasMode = Long.parseLong(request.getParameter(parameterPrefix + "natEngine.aliasMode"));
                                }
                                catch(NumberFormatException e){}

                                natEngine.setAliasMode(aliasMode);
                            }
                            else
                                ;

                            int numberOfCurrentRules = 0;
                            try
                            {
                                numberOfCurrentRules = Integer.parseInt(request.getParameter(parameterPrefix + "natEngine.numberOfRules"));
                            }
                            catch(NumberFormatException e){}

                            for(int ii = 0; ii < numberOfCurrentRules; ii++)
                            {
                                String rulePrefix = parameterPrefix + "natEngine.rule" + ii + ".";
                                if(request.getParameter(parameterPrefix + "remove") != null)
                                    natEngine.removeExistingForwardingRule(request.getParameter(rulePrefix + "name"));
                                else
                                    ;
                            }

                            int numberOfNewRules = 0;
                            try
                            {
                                numberOfNewRules = Integer.parseInt(request.getParameter(parameterPrefix + "natEngine.numberOfNewRules"));
                            }
                            catch(NumberFormatException e){}

                            for(int ii = 0; ii < numberOfNewRules; ii++)
                            {
                                String rulePrefix = parameterPrefix + "natEngine.newRule" + ii + ".";

                                int hostPort = 0, guestPort = 0;
                                try
                                {
                                    hostPort = Integer.parseInt(request.getParameter(rulePrefix + "hostPort"));
                                    guestPort = Integer.parseInt(request.getParameter(rulePrefix + "guestPort"));
                                }
                                catch(NumberFormatException e){}

                                natEngine.addNewForwardingRule(new NATEngineForwardingRule(request.getParameter(rulePrefix + "name"),
                                                                                           NATProtocol.valueOf(request.getParameter(rulePrefix + "protocol")),
                                                                                           request.getParameter(rulePrefix + "hostIP"),
                                                                                           hostPort,
                                                                                           request.getParameter(rulePrefix + "guestIP"),
                                                                                           guestPort));
                            }

                            networksSettings[i].setNatEngineSetup(natEngine);
                        }
                        else
                            ;
                    }
                    else
                        networksSettings[i] = new NetworkAdapterLiveSettings();
                }

                ((ModifyMachineLiveSettingsRequest)machineRequest).setNetworksSettings(networksSettings);
            }
            else
                ;
        } break;

        //modify machine storage settings request
        case 6:
        {
            //retrieves the supplied parameters and builds the request object
            StorageSettings storageSettings = new StorageSettings();

            int numberOfCurrentControllers = 0;
            try
            {
                numberOfCurrentControllers = Integer.parseInt(request.getParameter("modify.storage.controllers.number"));
            }
            catch(NumberFormatException e){}

            //retrieves the storage controllers for removal
            for(int i = 0; i < numberOfCurrentControllers; i++)
            {
                String parameterPrefix = "modify.storage.controller" + i + ".";
                if(request.getParameter(parameterPrefix + "remove") != null)
                    storageSettings.removeStorageController(request.getParameter(parameterPrefix + "name"));
                else
                    ;
            }

            int numberOfCurrentAttachments = 0;
            try
            {
                numberOfCurrentAttachments = Integer.parseInt(request.getParameter("modify.storage.attachments.number"));
            }
            catch(NumberFormatException e){}

            //retrieves the attachments for detachment
            for(int i = 0; i < numberOfCurrentAttachments; i++)
            {
                String parameterPrefix = "modify.storage.attachment" + i + ".";
                if(request.getParameter(parameterPrefix + "detach") != null)
                {
                    int controllerPort = -1;
                    int controllerSlot = -1;
                    try
                    {
                        controllerPort = Integer.parseInt(request.getParameter(parameterPrefix + "controllerPort"));
                        controllerSlot = Integer.parseInt(request.getParameter(parameterPrefix + "controllerSlot"));
                    }
                    catch(NumberFormatException e){}

                    storageSettings.detachExistingMedium(new DeviceSettings(request.getParameter(parameterPrefix + "controllerName"),
                                                                            controllerPort,
                                                                            controllerSlot,
                                                                            DeviceType.valueOf(request.getParameter(parameterPrefix + "deviceType"))));
                }
                else
                    ;
            }

            int numberOfNewControllers = 0;
            try
            {
                numberOfNewControllers = Integer.parseInt(request.getParameter("modify.storage.controllers.newNumber"));
            }
            catch(NumberFormatException e){}

            //retrieves the new controllers
            for(int i = 0; i < numberOfNewControllers; i++)
            {
                String parameterPrefix = "modify.storage.controllers.newController" + i + ".";
                storageSettings.addStorageController(new ControllerSettings(request.getParameter(parameterPrefix + "name"),
                                                                            StorageBus.valueOf(request.getParameter(parameterPrefix + "connectionType")),
                                                                            StorageControllerType.valueOf(request.getParameter(parameterPrefix + "controllerType")),
                                                                            request.getParameter(parameterPrefix + "hostIOCache") != null));
            }

            int numberOfNewAttachments = 0;
            try
            {
                numberOfNewAttachments = Integer.parseInt(request.getParameter("modify.storage.attachments.newNumber"));
            }
            catch(NumberFormatException e){}

            //retrieves the new attachments
            for(int i = 0; i < numberOfNewAttachments; i++)
            {
                String parameterPrefix = "modify.storage.attachments.newAttachment" + i + ".";

                int controllerPort = -1;
                int controllerSlot = -1;
                try
                {
                    controllerPort = Integer.parseInt(request.getParameter(parameterPrefix + "controllerPort"));
                    controllerSlot = Integer.parseInt(request.getParameter(parameterPrefix + "controllerSlot"));
                }
                catch(NumberFormatException e){}

                DeviceSettings deviceSettings = new DeviceSettings(request.getParameter(parameterPrefix + "controllerName"),
                                                                   controllerPort,
                                                                   controllerSlot,
                                                                   DeviceType.valueOf(request.getParameter(parameterPrefix + "deviceType")),
                                                                   request.getParameter(parameterPrefix + "mediumId"));

                //checks if a new medium is to be created
                if(request.getParameter(parameterPrefix + "newMedium") != null)
                {
                    //retrieves the new medium parameters
                    MediumManagementRequest mediumRequestData = null;

                    String format = request.getParameter(parameterPrefix + "newMedium.format");
                    String location = request.getParameter(parameterPrefix + "newMedium.location");
                    MediumVariant variant = MediumVariant.valueOf(request.getParameter(parameterPrefix + "newMedium.variant"));
                    String permissions = request.getParameter(parameterPrefix + "newMedium.permissions");

                    if(request.getParameter(parameterPrefix + "newMedium").equals("1")) //normal disk
                    {
                        long logicalSize = 0;
                        try
                        {
                            logicalSize = Long.parseLong(request.getParameter(parameterPrefix + "newMedium.size"));
                        }
                        catch(NumberFormatException e){}

                        mediumRequestData = new CreateHardDiskRequest(userSessionData.getUserData().getUserId(),
                                                                      userSessionData.getCurrentServerId(),
                                                                      format,
                                                                      location,
                                                                      variant,
                                                                      logicalSize,
                                                                      permissions);
                    }
                    else if(request.getParameter(parameterPrefix + "newMedium").equals("2"))//differencing disk
                    {
                        mediumRequestData = new CreateHardDiskRequest(userSessionData.getUserData().getUserId(),
                                                                      userSessionData.getCurrentServerId(),
                                                                      format,
                                                                      location,
                                                                      variant,
                                                                      permissions,
                                                                      request.getParameter(parameterPrefix + "newMedium.parentId"));
                    }
                    else
                        ;

                    storageSettings.attachNewMedium(deviceSettings, mediumRequestData);
                }
                else
                    storageSettings.attachExistingMedium(deviceSettings);
            }

            machineRequest = new ModifyMachineStorageRequest(userSessionData.getUserData().getUserId(),
                                                             userSessionData.getCurrentServerId(),
                                                             request.getParameter("id"),
                                                             storageSettings);
        } break;

        //mount/unmount media request
        case 7:
        {
            //retrieves the supplied parameters and builds the request object
            int controllerPort = -1;
            int controllerSlot = -1;

            try
            {
                controllerPort = Integer.parseInt(request.getParameter("controllerPort"));
                controllerSlot = Integer.parseInt(request.getParameter("controllerSlot"));
            }
            catch(NumberFormatException e){}

            MediumMountSettings mountSettings = new MediumMountSettings(request.getParameter("controllerName"),
                                                                        controllerPort,
                                                                        controllerSlot,
                                                                        request.getParameter("mediumId"),
                                                                        request.getParameter("force") != null);

            machineRequest = new MountMediumRequest(userSessionData.getUserData().getUserId(),
                                                    userSessionData.getCurrentServerId(),
                                                    request.getParameter("id"),
                                                    mountSettings);
        } break;

        //remove machine request
        case 8:
        {
            machineRequest = new RemoveMachineRequest(userSessionData.getUserData().getUserId(),
                                                      userSessionData.getCurrentServerId(),
                                                      request.getParameter("id"),
                                                      request.getParameter("force") != null);
        } break;

        default: ;
    }

    //attempts to send the request and retrieves the response
    SendingRequestResult sendingResult = UIFunctions.sendServiceRequest(request, response, machineRequest, Service.MACHINES_MANAGEMENT);
    if(sendingResult != SendingRequestResult.OK)
    {
        //retrieves the user's messages container
        ResponseMessagesContainer messagesContainer =
            (ResponseMessagesContainer)request.getSession(false).getAttribute(ParameterNames.SESSION_REQUEST_MESSAGES_OBJECT);

        int exceptionCode = UIFunctions.parseSendingRequestResult(sendingResult);

        //adds the response from the failed operation
        MachineManagementResponse machineResponse = new MachineManagementResponse(false, new ApplicationException(exceptionCode));
        messagesContainer.put(new RequestResponseWrapper(machineRequest, machineResponse));
    }
    else
        ;

    //based on the requested action, the proper redirect page is selected
    if(Functions.isUUIDValid(request.getParameter("id")) && action != 8 && action != 2)
    {
        if(action == 3)
            response.sendRedirect("snapshots.jsp?id=" + request.getParameter("id"));
        else
            response.sendRedirect("machines.jsp?id=" + request.getParameter("id"));
    }
    else
        response.sendRedirect("machines.jsp");
%>